package com.shopng.server.commands;

import java.util.Properties;

import org.apache.commons.lang.StringUtils;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.distributed.ServerLauncher;
import org.apache.geode.distributed.ServerLauncher.Builder;
import org.apache.geode.distributed.ServerLauncher.ServerState;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;
import org.kohsuke.args4j.OptionHandlerRegistry;
import org.kohsuke.args4j.spi.StringArrayOptionHandler;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.shopng.utils.ConfigHelper;
import com.shopng.utils.ConfigHelper.ITEMS;
import com.shopng.utils.LogUtil;
import com.shopng.utils.Util;
import com.shopng.utils.WorkPathHelper;

@SpringBootApplication
public class GeodServer
{
  @Option(name = "-name", usage = "work path")
  private String serverName;
  @Option(name = "-configXml", usage = "work path")
  private String configXml = "server.xml";
  
  private static GeodServer  gsInstance = new GeodServer();
  
  public GeodServer()
  {
    
  }
  
  public final static GeodServer getInstance()
  {
    return gsInstance;
  }

  /**
   * @param args
   * @throws Exception
   */
  public static void main(String[] args) throws Exception
  {
    GeodServer.getInstance().start(args);
  }
  
  public void start(String[] args)
  {
    Properties props = ConfigHelper.getConfig("gemfire.properties");
    Builder builder = new Builder();
    props.forEach((propertyName,propertyValue)->{
      builder.set((String)propertyName, (String)propertyValue);
    });
    ConfigHelper.initConfig();
    ConfigHelper.setProperty(ITEMS.NODE_TYPE.name(), "server");
    OptionHandlerRegistry.getRegistry().registerHandler(String[].class, StringArrayOptionHandler.class);
    CmdLineParser cp = new CmdLineParser(gsInstance);
    try
    {
      cp.parseArgument(args);
    }
    catch (CmdLineException e)
    {
      e.printStackTrace();
      System.exit(-1);
    }
    if (StringUtils.isBlank(serverName))
    {
      serverName = WorkPathHelper.verifyServerName(ITEMS.GS_WORK, "server", serverName);
    }
    ConfigHelper.setProperty(ConfigHelper.ITEMS.NODE_NAME.name(), serverName);
    ConfigHelper.initLog4j();
    ConfigHelper.setMemberName(serverName);
    StringBuilder buil = new StringBuilder();
    buil.append(ConfigHelper.getConfig(ITEMS.GS_WORK)).append("/").append("server").append("/").append(serverName);
    ConfigHelper.setProperty(ITEMS.NODE_WORK_DIR, buil.toString());
    WorkPathHelper.verifyPath("deploy");
    builder.setServerBindAddress(ConfigHelper.getConfig(ITEMS.BINDIP));
    builder.setWorkingDirectory(buil.toString());
    System.setProperty("workdir",  buil.toString());
    builder.set("cache-xml-file", configXml);
    builder.set("locators", ConfigHelper.getConfig(ITEMS.LOCATORS));
    StringBuilder af = new StringBuilder();
    af.append(ConfigHelper.getHomePath()).append("/").append("/log/gfs/server-").append(serverName).append(".gfs");
    builder.set("statistic-archive-file", af.toString());
    builder.set("deploy-working-dir", ConfigHelper.getConfig(ITEMS.DEPLOY_WORKING_DIR));
    builder.setMemberName("server-"+serverName);
    builder.set("log-file", ConfigHelper.getConfig(ITEMS.GS_HOME)+"/log/server-"+serverName+".log");
    //set server port
    int port = Util.randomPort();
    builder.setServerPort(port);
    ServerLauncher severLauncher = builder.build();
    ServerState state = severLauncher.start();
    
    Cache cache = CacheFactory.getAnyInstance();
    System.out.println("Server status:"+state.getStatus()+" Port:"+port);
    LogUtil.getCoreLog().info("Server status:{},port:{}",state.getStatus(),port);
    
    DistributedMember m = cache.getDistributedSystem().getDistributedMember();
    String memberId = m.getId();
    ConfigHelper.setProperty(ITEMS.MEMBER_ID.name(), memberId);
    LogUtil.getCoreLog().info("Cacheserver " + serverName + "(" + memberId + "/" + Util.getPID() + ") started.");
    
    severLauncher.waitOnServer();
  }
}
